#!/usr/bin/python

### README ###
# You can make a config file called .gooshell in your home directory
# Syntax is on the Wiki on Google Code
# Variable com is two parts. com[0] is the base command input, com[1:] is anything after
# This program should be really easily moddable and you can add anything to it
'''
    This program is released under the GNU General Public License
    version 3.

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
'''

### IMPORTS ###

from os import system
from commands import getoutput
from webbrowser import open_new_tab
from re import compile

### END IMPORTS ###

### DEFAULTS ###

url      = {'web': 'http://www.google.com/search?q=', 'img': 'http://www.google.com/images?q=', 'vid': 'http://www.google.com/#tbm=vid&q=', 'maps': 'http://maps.google.com/maps?q=', 'news': 'http://news.google.com/news?q=', 'shop': 'http://www.google.com/search?tbs=shop:1&q=', 'wmmd': 'http://en.wikipedia.org/wiki/'} # Dictionary containing base URLs for search command
cddb     = ['img', 'maps', 'news', 'shop', 'vid', 'web', 'wmmd'] # cd database
mode     = 'web' # Default mode
server   = 'gooshell' # Default server name
homedir  = getoutput('echo $HOME')
user     = getoutput('echo $USER')
defbrow  = ''
tops     = 5
valcom   = ['cd', 'clear', 'exit', 'help', 'ls', 'search', 'wikimode'] ## Valid commands

auth = 'Kyle Clemens'
ver  = '2.1pre'
emai = 'jkc.clemens@gmail.com'

### END DEFAULTS ###

### PRECURSORS ###

try:
	a = file('%s/.gooshell' % homedir, 'r') # Try to load conf file
except:
	pass
else:
	settings = a.read()
	a.close()
	print "Found custom settings file."
	print "Using custom settings."
	settings = settings.split('\n')
	for line in settings:
		if line.startswith('defbrow '):
			defbrow = line
			defbrow = defbrow.replace('defbrow ', '', 1)
		if line.startswith('servname '):
			server = line
			server = server.replace('servname ', '', 1)
		if line.startswith('defmode '):
			mode = line.replace("defmode ", '', 1)
			if mode not in cddb:
				mode = 'web'
				print "Config file error: %s not a valid mode" % line.replace('defmode ', '', 1)
		if line.startswith('resultsn '):
			tops = line.replace('resultsn ', '')
			res = compile(r'[^\d]+')
			tops = res.sub('', tops)
			tops = int(tops) + 1
			if tops == '':
				tops = 5
			

### END PRECURSORS ###

### FUNCTIONS ###

def help():
	print "gooshell v%s" % ver
	print "Created by %s <%s>" % (auth, emai)
	print "gooshell is a shell for Google Search Engine. It is not an official Google product."
	print "List of commands:"
	for value in valcom:
		print value

def rep(result):
    string = result.group()                   # "&#xxx;"
    n = int(string[2:-1])
    uchar = unichr(n)                         # matching unicode char
    # for you dest format may be iso-8859-2 ?
    return unicode.encode(uchar, "utf-8")     # format-encoded char

def remstup(data):
	return data.replace("&quot;", "'").replace("&nbsp;", " ").replace("&amp;", "&")

def webopen(url, term): ## Open URL 'url' with default browser or defbrow in conf file
	global defbrow
	global tops
	if mode == 'wmmd':
		pat = compile("""&#\d+;""")
		data = getoutput('curl %s' % url)
		data = data.partition('<p>')
		data = data[2].partition('</p>')
		data = remove_html_tags(data[0])
		print pat.sub(rep, remstup(data))
		print
		print "More at: %s" % url
	elif mode == 'web':
		googpage = getoutput("curl --silent \"%s\" -A \"Mozilla/5.0 (X11; Linux x86_64; rv:2.2a1pre) Gecko/20110324 Firefox/4.2a1pre\"" % url)
		googpage = googpage.partition('<h2 class=hd>Search Results</h2>')
		googpage = googpage[2].partition('</ol>')
		googpage = googpage[0].split("<h3 class=\"r\">")
		googleng = len(googpage)
		counter = 1
		while counter < tops:
			if counter < googleng:
				pat = compile("""&#\d+;""")
				title = googpage[counter].partition('</h3>')[0]
				print str(counter) + ". " + pat.sub(rep, remstup(remove_html_tags(title)))
				try:
					desc =  "      " + remove_html_tags(googpage[counter].partition('</h3>')[2].split("<div class=\"s\">")[1].partition('<span class=f')[0])
				except:
					desc =  "      " + remove_html_tags(googpage[counter].partition('</h3>')[2].split("<div class=\"s\">")[0].partition('<span class=f')[0])
				else:
					pass
				pat = compile("""&#\d+;""")
				print pat.sub(rep, remstup(desc))
				print "      " + remove_html_tags(googpage[counter].partition('</h3>')[0].split("<a href=\"")[1].partition('\"')[0])
				print
				counter = counter + 1
	else:
		if defbrow == '':
			print
			open_new_tab(sturl)
		else:
			print
			system('%s \'%s\'' % (defbrow, url))

def remove_html_tags(data):
    p = compile(r'<[^<]*?>')
    return p.sub('', data)

def exit():
	quit()

def misarg(): ## Missing args
	print "Command '%s' is missing arguments. Use command 'help' to find out syntax." % com[0]
	
def main():
	global com
	global mode
	if mode == 'wmmd':
		com = raw_input("%s@%s:%s# " % (user, server, mode)).split(" ")
		com[0] = com[0].lower()
	else:
		com = raw_input("%s@%s:%s# " % (user, server, mode)).lower().split(" ")
	if com[0] not in valcom:
		print "Unknown command: %s" % com[0]
	else:
		if com[0] == 'exit':
			exit()
		elif com[0] == 'ls':
			for value in cddb:
				print value
		elif com[0] == 'help':
			help()
		elif com[0] == 'clear':
			system('clear')
		elif com[0] == 'wikimode':
			print "Wikimode searches Wikipedia and tries to withdraw the first paragraph of information on your search terms. Capitalization MATTERS."
			mode = 'wmmd'
		elif com[0] == 'search':
			try:
				com[1]
			except IndexError:
				misarg()
			else:
				st = com[1:]
				st = ' '.join(st)
				if mode == 'wmmd':
					st = st.replace(' ', '_')
				else:
					st = st.replace(" ", "%20")
				sturl = url[mode] + st
				webopen(sturl, st)
		elif com[0] == 'cd':
			try:
				com[1]
			except IndexError:
				misarg()
			else:
				if com[1] in cddb:
					if com[1] == 'wmmd':
						print "Use the command 'wikimode' to enable this mode."
					else:
						mode = com[1].lower()
				else:
					print "Mode '%s' is not a valid mode. Try 'ls' for mode listing." % com[1]

### END FUNCTIONS ###

### MAIN WORKLOAD ###
		
while True:
	main()

### END MAIN WORKLOAD ###

quit() # Trailing quit for safety...
